/* hal_uart.c */
#include "hal_uart.h"

void UART_Init(UART_Type * UARTx, UART_Init_Type * init)
{
    /* setup the transfer. */
    uint32_t ctrl_reg = UART_CTRL_CTS_DIS_MASK;
    ctrl_reg |= (((init->RxFifoThreshold) << UART_CTRL_RX_THD_VAL_SHIFT) & UART_CTRL_RX_THD_VAL_MASK);
    ctrl_reg |= (((init->Parity) << UART_CTRL_PAR_EN_SHIFT) & (UART_CTRL_PAR_EN_MASK | UART_CTRL_PAR_EO_MASK));
    ctrl_reg |= (((init->DataBits) << UART_CTRL_CHAR_SIZE_SHIFT) & UART_CTRL_CHAR_SIZE_MASK);
    ctrl_reg |= ((init->StopBits == UART_StopBits_1b) ? 0u : UART_CTRL_STOPBITS_MASK);
    UARTx->CTRL = ctrl_reg; /* baudrate clock is still off. */

    /* setup baudrate. */
	UARTx->CLKDIV = init->BaudrateClkSrcHz / init->Baudrate;
    UARTx->CTRL |= UART_CTRL_BCLKEN_MASK /* enable the baudrate clock. */
    			| (((init->BaudrateClkSrc) << UART_CTRL_BCLKSRC_SHIFT) & UART_CTRL_BCLKSRC_MASK)
    			;
    /* wait until the baudrate clock is ready. */
    while (0u == (UARTx->CTRL & UART_CTRL_BCLKRDY_MASK))
    {}
}

void UART_ResetRxFifo(UART_Type * UARTx)
{
    UARTx->CTRL |= UART_CTRL_RX_FLUSH_MASK;
}

void UART_ResetTxFifo(UART_Type * UARTx)
{
    UARTx->CTRL |= UART_CTRL_TX_FLUSH_MASK;
}

void UART_PutTxFifoData(UART_Type * UARTx, uint8_t dat)
{
    UARTx->FIFO = dat;
}

uint8_t UART_GetRxFifoData(UART_Type * UARTx)
{
    return (uint8_t)(UARTx->FIFO);
}

uint32_t UART_GetStatus(UART_Type * UARTx)
{
	return UARTx->STATUS;
}

uint32_t UART_GetRxFifoCount(UART_Type * UARTx)
{
	return (UARTx->STATUS & UART_STATUS_RX_LVL_MASK) >> UART_STATUS_RX_LVL_SHIFT;
}

uint32_t UART_GetTxFifoCount(UART_Type * UARTx)
{
	return (UARTx->STATUS & UART_STATUS_TX_LVL_MASK) >> UART_STATUS_TX_LVL_SHIFT;
}

uint32_t UART_GetInterruptStatus(UART_Type * UARTx)
{
    return UARTx->INT_FL;
}

void UART_ClearInterruptStatus(UART_Type * UARTx, uint32_t flags)
{
    UARTx->INT_FL = flags;
}

void UART_EnableInterrupts(UART_Type * UARTx, uint32_t flags, bool enable)
{
    if (enable)
    {
    	UARTx->INT_EN |= flags;
    }
    else
    {
    	UARTx->INT_EN &= ~flags;
    }
}

uint32_t UART_GetEnabledInterrupts(UART_Type * UARTx)
{
	return UARTx->INT_EN;
}

/* TODO: support DMA. */

/* EOF. */

